/*
 * 
 * 
 * 
 */
package com.hboxs.asl.dao;

import com.hboxs.asl.Filter;
import com.hboxs.asl.Page;
import com.hboxs.asl.Pageable;
import com.hboxs.asl.entity.Member;
import com.hboxs.asl.entity.Order;
import com.hboxs.asl.entity.Order.OrderStatus;
import com.hboxs.asl.entity.Order.PaymentStatus;
import com.hboxs.asl.entity.Order.ShippingStatus;
import com.hboxs.asl.entity.Product;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Dao - 订单
 */
public interface OrderDao extends BaseDao<Order, Long> {

    /**
     * 根据订单编号查找订单
     *
     * @param sn 订单编号(忽略大小写)
     * @return 订单，若不存在则返回null
     */
    Order findBySn(String sn);

    /**
     * 查找订单
     *
     * @param member  会员
     * @param count   数量
     * @param filters 筛选
     * @param orders  排序
     * @return 订单
     */
    List<Order> findList(Member member, Integer count, List<Filter> filters, List<com.hboxs.asl.Order> orders);

    /**
     * 查找订单分页
     *
     * @param member   会员
     * @param pageable 分页信息
     * @return 订单分页
     */
    Page<Order> findPage(Member member, Pageable pageable);

    /**
     * 查找订单分页
     *
     * @param orderStatus    订单状态
     * @param paymentStatus  支付状态
     * @param shippingStatus 配送状态
     * @param hasExpired     是否已过期
     * @param pageable       分页信息
     * @return 商品分页
     */
    Page<Order> findPage(OrderStatus orderStatus, PaymentStatus paymentStatus, ShippingStatus shippingStatus, Boolean hasExpired, Pageable pageable);

    /**
     * 查找订单分页
     *
     * @param member         会员
     * @param orderStatus    订单状态
     * @param paymentStatus  支付状态
     * @param shippingStatus 配送状态
     * @param hasExpired     是否已过期
     * @param hasReview     是否已评论
     * @param hasApplyReturn 是否申请退换货
     * @param pageable       分页信息
     * @return 商品分页
     */
    Page<Order> findPage(Member member, OrderStatus orderStatus, PaymentStatus paymentStatus, ShippingStatus shippingStatus, Boolean hasExpired, Boolean hasReview, Boolean hasApplyReturn, Pageable pageable);

    /**
     * 查询订单数量
     *
     * @param orderStatus    订单状态
     * @param paymentStatus  支付状态
     * @param shippingStatus 配送状态
     * @param hasExpired     是否已过期
     * @return 订单数量
     */
    Long count(OrderStatus orderStatus, PaymentStatus paymentStatus, ShippingStatus shippingStatus, Boolean hasExpired);

    /**
     * 查询订单数量
     *
     * @param member         會員
     * @param orderStatus    订单状态
     * @param paymentStatus  支付状态
     * @param shippingStatus 配送状态
     * @param hasExpired     是否已过期
     * @param hasApplyReturn 是否申请退换货
     * @return 订单数量
     */
    Long count(Member member, OrderStatus orderStatus, PaymentStatus paymentStatus, ShippingStatus shippingStatus, Boolean hasExpired, Boolean hasReview, Boolean hasApplyReturn);

    /**
     * 查询等待支付订单数量
     *
     * @param member 会员
     * @return 等待支付订单数量
     */
    Long waitingPaymentCount(Member member);

    /**
     * 获取待支付订单分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> findWaitingPaymentPage(Member member, Pageable pageable);

    /**
     * 查询等待发货订单数量
     *
     * @param member 会员
     * @return 等待发货订单数量
     */
    Long waitingShippingCount(Member member);

    /**
     * 获取待发货订单分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> findWaitingShippingPage(Member member, Pageable pageable);

    /**
     * 获取待收货订单分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> receivedPage(Member member, Pageable pageable);

    /**
     * 获取待评价的商品分页
     * @param member
     * @param pageable
     * @return
     */
    Page<Order> pendingEvaluationPage(Member member, Pageable pageable);

    /**
     * 获取销售额
     *
     * @param beginDate 起始日期
     * @param endDate   结束日期
     * @return 销售额
     */
    BigDecimal getSalesAmount(Date beginDate, Date endDate);

    /**
     * 获取已支付订单销售额
     *
     * @param beginDate 起始日期
     * @param endDate   结束日期
     * @return 销售额
     */
    BigDecimal getPaySalesAmount(Date beginDate, Date endDate);


    /**
     * 获取销售量
     *
     * @param beginDate 起始日期
     * @param endDate   结束日期
     * @return 销售量
     */
    Integer getSalesVolume(Date beginDate, Date endDate);

    /**
     * 释放过期订单库存
     */
    void releaseStock();


    /**
     * 查询订单数量
     *
     * @param orderStatus           状态
     * @param member           会员
     * @param product            货品
     * @param isAllocatedStock 是否已分配库存
     * @param hasExpired       是否已过期
     * @return 订单数量
     */
    Long count(Order.OrderStatus orderStatus, Member member, Product product, Boolean isAllocatedStock, Boolean hasExpired);

}